package com.example.dense_rack_server.controller;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.dense_rack_server.entity.*;
import com.example.dense_rack_server.excel.ArchivesBatchImport;
import com.example.dense_rack_server.excel.ArchivesBatchListener;
import com.example.dense_rack_server.mapper.ElectronArchivesMapper;
import com.example.dense_rack_server.mapper.SysParamsetMapper;
import com.example.dense_rack_server.security.dto.JwtUserDto;
import com.example.dense_rack_server.service.*;
import com.example.dense_rack_server.utils.DateFormat;
import com.example.dense_rack_server.utils.ResponseModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 档案表 前端控制器
 * </p>
 *
 * @author 张彬
 * @since 2025-03-03
 */
@Controller
@RequestMapping("/archives")
public class ArchivesController {

    @Resource
    public ArchivesService archivesService;
    @Resource
    public MyUserService myUserService;
    @Resource
    public HostService hostService;
    @Resource
    public ArchivesAreaService archivesAreaService;
    @Resource
    public BorrowingRecordsService borrowingRecordsService;
    @Resource
    public SysParamsetMapper sysParamsetMapper;
    @Resource
    public ElectronArchivesMapper electronArchivesMapper;
    @Resource
    public QrcodeService qrcodeService;

    @Value("${SavePath.nginxPath}")
    private String nginxPath;
    @Resource
    public SysParamsetService sysParamsetService;

    @GetMapping("/index")
    public ModelAndView index() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("archives/table-list");
        SysParamset sysParamset = sysParamsetService.getById(2);
        modelAndView.addObject("sysType", Convert.toInt(sysParamset.getParamValue()));
        return modelAndView;
    }


    /**
     * 档案数据
     */
    @ResponseBody
    @GetMapping("/list")
    public Map<String, Object> ArchiveList(@RequestParam(value = "fileName", required = false) String fileName,
                                           @RequestParam(value = "archiveArea", required = false) String archiveArea,
                                           @RequestParam(value = "year", required = false) String year,
                                           @RequestParam(value = "areaId", required = false) String areaId,
                                           @RequestParam(value = "page") int page,
                                           @RequestParam(value = "limit") int limit) {
        return archivesService.ArchiveList(fileName, archiveArea, year, areaId, page, limit);
    }


    /**
     * 档案新增页面
     */
    @GetMapping("/insert/add")
    public ModelAndView add() {
        ModelAndView modelAndView = new ModelAndView("archives/add");
        List<MyUser> userList = myUserService.list(new QueryWrapper<MyUser>().eq("status", 1));
        modelAndView.addObject("userList", userList);
        JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userName = jwtUserDto.getUsername();
        modelAndView.addObject("userName", userName);
        modelAndView.addObject("uuid", IdUtil.simpleUUID());

        SysParamset sysParamset = sysParamsetService.getById(2);
        modelAndView.addObject("sysType", Convert.toInt(sysParamset.getParamValue()));

        List<Host> hostList = hostService.list();
        modelAndView.addObject("hostList", hostList);
        return modelAndView;
    }

    /**
     * 档案新增
     */
    @ResponseBody
    @PostMapping("/insert/save")
    public ResponseModel archiveInsert(@RequestBody JSONObject data) {
        return archivesService.archiveInsert(data);
    }

    /**
     * 档案编辑页面
     */
    @GetMapping("/edit/{archive_id}")
    public ModelAndView edit(@PathVariable("archive_id") String archive_id) {
        Archives archives = archivesService.getById(archive_id);
        if (archives == null) {
            return new ModelAndView("error/404");
        }
        ModelAndView modelAndView = new ModelAndView("archives/edit");
        modelAndView.addObject("archives", archives);
        List<MyUser> userList = myUserService.list();
        modelAndView.addObject("userList", userList);


        ArchivesArea archivesArea = archivesAreaService.getOne(new QueryWrapper<ArchivesArea>().eq("id", archives.getArchivesAreaId()));
        modelAndView.addObject("archivesArea", archivesArea);

        List<Host> hostList = hostService.list();
        modelAndView.addObject("hostList", hostList);

        // 查询当前存档所在区域
        Host host = hostService.getOne(new QueryWrapper<Host>().eq("cabinet_number", archives.getAreaCode()));
        // 列号
        List<Integer> columnList = new ArrayList<>();
        for (int i = 1; i <= host.getColumnNumber(); i++) {
            columnList.add(i);
        }
        modelAndView.addObject("columnList", columnList);
        // 节数
        List<Integer> joinList = new ArrayList<>();
        for (int i = 1; i <= host.getCabinetJoint(); i++) {
            joinList.add(i);
        }
        modelAndView.addObject("joinList", joinList);
        // 层数
        List<Integer> layerList = new ArrayList<>();
        for (int i = 1; i <= host.getCabinetLayer(); i++) {
            layerList.add(i);
        }
        modelAndView.addObject("layerList", layerList);
        // 位置
        List<Integer> positionList = new ArrayList<>();
        for (int i = 1; i <= host.getRfidNumber(); i++) {
            positionList.add(i);
        }
        modelAndView.addObject("positionList", positionList);

        String sysType = sysParamsetMapper.selectById(2).getParamValue();
        modelAndView.addObject("sysType", sysType);
        return modelAndView;
    }

    /**
     * 档案编辑保存
     */
    @ResponseBody
    @PostMapping("/edit/save")
    public ResponseModel editSave(@RequestBody JSONObject data) {
        return archivesService.editSave(data);
    }

    /**
     * 档案详情
     */
    @GetMapping("/info/view")
    @ResponseBody
    public ModelAndView archiveDetail(@RequestParam(value = "archiveId") int archiveId) {
        return archivesService.archiveDetail(archiveId);
    }

    /**
     * 档案删除
     */
    @ResponseBody
    @DeleteMapping("/delete/save/{archiveId}")
    public ResponseModel deleteSave(@PathVariable("archiveId") String archiveId) throws InterruptedException {
        return archivesService.deleteSave(archiveId);
    }

    /**
     * 取出档案视图
     */
    @GetMapping("/takeout/view")
    public ModelAndView takeoutView(@RequestParam(value = "archiveId") String archiveId) {
        return archivesService.takeoutView(archiveId);
    }

    /**
     * 取出档案保存
     */
    @PostMapping("/takeout/save")
    @ResponseBody
    public ResponseModel takeOutSave(@RequestBody JSONObject data) throws InterruptedException {
        return archivesService.takeOutSave(data);
    }

    /**
     * 归还档案保存
     */
    @PostMapping("/return/save")
    @ResponseBody
    public ResponseModel returnSave(@RequestBody JSONObject data) throws InterruptedException {
        return archivesService.returnSave(data);
    }


    /**
     * 统计数据
     */
    @GetMapping("/statistics")
    @ResponseBody
    public ModelAndView statistics() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("archives/statistics");

        List<BorrowingRecords> borrowingRecordsList = borrowingRecordsService.list(
                new QueryWrapper<BorrowingRecords>().eq("module_type", 2)
                        .orderByDesc("create_time").last("limit 6"));
        modelAndView.addObject("borrowingRecordsList", borrowingRecordsList);

        Date nowDate = DateUtil.date();
        Date StartDate = DateUtil.offset(nowDate, DateField.MONTH, -6);
        modelAndView.addObject("startDate", DateUtil.format(StartDate, "yyyy-MM-dd"));
        modelAndView.addObject("endDate", DateUtil.format(nowDate, "yyyy-MM-dd"));
        return modelAndView;
    }


    /**
     * 档案类型统计
     *
     * @return
     */
    @GetMapping("/statistics/type")
    @ResponseBody
    public Map<String, Object> archiveTypeStatistics() {
        return archivesService.archiveTypeStatistics();
    }

    /**
     * 档案存取统计
     *
     * @return
     */
    @GetMapping("/statistics/access")
    @ResponseBody
    public Map<String, Object> archiveAccessStatistics(@RequestParam(value = "selectStartDate", required = false) String selectStartDate,
                                                       @RequestParam(value = "selectEndDate", required = false) String selectEndDate) throws ParseException {
        return archivesService.archiveAccessStatistics(selectStartDate, selectEndDate);
    }


    /**
     * 批量插入测试数据
     *
     * @return
     */
    @GetMapping("/insert")
    @ResponseBody
    public ResponseModel insert() {
        for (int i = 0; i < 50; i++) {
            Archives archives = new Archives();
            int randomInt = RandomUtil.randomInt(1000, 10000);
            archives.setFileName("档案测试" + randomInt);
            archives.setFileId("编号" + randomInt);
            archives.setYear("2021");
            archives.setUserName("admin" + i);
            archives.setProfile("档案描述" + i);
            archives.setStatus(RandomUtil.randomInt(0, 2));
            archives.setElectronFileStatus(0);
            archives.setArchivesAreaId(41);
            archives.setArchivesTypeId(7);
            archives.setCreateTime(DateFormat.getTime());
            archives.setUpdateTime(DateFormat.getTime());
            archives.setAreaCode(21);
            archives.setColumnNumber(RandomUtil.randomInt(1, 5));
            int result = RandomUtil.randomInt(0, 2);
            archives.setDenseRackRegion(result);
            archives.setJoint(RandomUtil.randomInt(1, 3));
            archives.setLayerNumber(RandomUtil.randomInt(1, 6));
            archives.setPosition(RandomUtil.randomInt(1, 10));
            archivesService.save(archives);
        }
        return ResponseModel.success("success");
    }

    /**
     * 扫码枪
     */
    @GetMapping("/scanning/gun")
    public String scanner() {
        return "archives/scanner";
    }

    /**
     * 打印二维码
     */
    @GetMapping("/print/qrCode")
    public ModelAndView qrCode(@RequestParam(value = "fileName") String fileName,
                               @RequestParam(value = "uuid") String uuid) {
        return archivesService.qrCode(fileName, uuid);
    }

    /**
     * 扫码枪获取档案信息
     */
    @GetMapping("/scanning/info")
    @ResponseBody
    public ResponseModel scannerGetArchives(@RequestParam(value = "uuid") String uuid) {
        return archivesService.scannerGetArchives(uuid);
    }


    /**
     * 扫码枪入库
     */
    @PostMapping("/scanning/gun/in")
    @ResponseBody
    public ResponseModel scannerGunIn(@RequestBody JSONObject data) throws InterruptedException {
        if (StrUtil.isEmpty(data.getStr("uuid"))) {
            return ResponseModel.fail("请扫描标签");
        }
        return archivesService.scannerGunIn(data);
    }


    /**
     * 扫码枪出库
     */
    @PostMapping("/scanning/gun/out")
    @ResponseBody
    public ResponseModel scannerGunOut(@RequestBody JSONObject data) throws InterruptedException {
        if (StrUtil.isEmpty(data.getStr("uuid"))) {
            return ResponseModel.fail("请扫描标签");
        }
        return archivesService.scannerGunOut(data);
    }

    /**
     * 批量生成二维码标签
     */
    @GetMapping("qrCode/table")
    public ModelAndView qrCodeTest() {
        return new ModelAndView("archives/qrcodeGenerationTable");
    }

    /**
     * 批量生成二维码标签
     */
    @GetMapping("qrCode/generate")
    @ResponseBody
    public ResponseModel generateQrCode(@RequestParam(value = "numberOfPrints") String numberOfPrints) {
        if (StrUtil.isEmpty(numberOfPrints)) {
            return ResponseModel.fail("请输入打印数量");
        }
        if (Convert.toInt(numberOfPrints) == 0) {
            return ResponseModel.fail("打印数量不能为0");
        }
        if (Convert.toInt(numberOfPrints) > 50) {
            return ResponseModel.fail("打印数量不能超过50");
        }
        List<Map<String, Object>> uuidList = new ArrayList<>();
        for (int i = 1; i <= Convert.toInt(numberOfPrints); i++) {
            Map<String, Object> map = new HashMap<>();
            String uuid = IdUtil.simpleUUID();
            map.put("serialNumber", i);
            map.put("uuid", uuid);
            map.put("create_time", DateFormat.getTime());
            uuidList.add(map);
        }
        Qrcode qrcode = new Qrcode();
        Map<String, Object> data = new HashMap<String, Object>() {{
            put("uuidList", uuidList);
        }};
        qrcode.setData(JSONUtil.toJsonStr(data));
        qrcodeService.save(qrcode);
        Map<String, Object> uuidListMap = new HashMap<>();
        uuidListMap.put("uuidList", uuidList);
        uuidListMap.put("qrCodeId", qrcode.getId());
        return ResponseModel.success(uuidListMap, "生成成功");
    }

    /**
     * 批量打印二维码
     */
    @GetMapping("/batch/qrCode/print")
    public ModelAndView qrCodeTest(@RequestParam(value = "qrCodeId") String qrCodeId, HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("archives/qrcodeGeneration");
        Qrcode qrcode = qrcodeService.getById(Convert.toInt(qrCodeId));
        if (qrcode != null) {
            JSONObject jsonObject = JSONUtil.parseObj(qrcode.getData());
            List<Map<String, Object>> uuidList = (List<Map<String, Object>>) jsonObject.get("uuidList");
            modelAndView.addObject("uuidList", uuidList);
            modelAndView.addObject("qrCodeId", qrCodeId);
        }
        return modelAndView;
    }

    /**
     * 删除批量打印二维码数据
     */
    @GetMapping("/batch/qrCode/delete")
    @ResponseBody
    public ResponseModel deleteQrCode(@RequestParam(value = "qrCodeId") String qrCodeId) {
        Qrcode qrcode = qrcodeService.getById(Convert.toInt(qrCodeId));
        if (qrcode == null) {
            return ResponseModel.fail("二维码不存在");
        }
        qrcodeService.removeById(Convert.toInt(qrCodeId));
        return ResponseModel.success("删除成功");
    }


    /**
     * 批量导入
     */
    @GetMapping("/batchImport/view")
    public ModelAndView batchImport() {
        ModelAndView modelAndView = new ModelAndView("archives/batchImport");
        JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer userId = jwtUserDto.getMyUser().getUserId();
        modelAndView.addObject("userId", userId);
        return modelAndView;
    }

    /**
     * 下载批量入库模版
     */
    @GetMapping("/batch/download/template")
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        String filePath = "static/excel/档案批量录入模版.xlsx";
        // 重要! 设置返回格式是excel形式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 设置编码格式
        response.setCharacterEncoding("utf-8");
        // 设置URLEncoder.encode 防止中文乱码
        String fileName = null;
        fileName = URLEncoder.encode("档案批量录入模版", "UTF-8").replaceAll("\\+", "%20");
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 模板文件保存在springboot项目的resources/static下
        org.springframework.core.io.Resource resource = new ClassPathResource(filePath);
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                .withTemplate(resource.getInputStream()) // 利用模板的输出流
                .build();
        excelWriter.finish();
    }


    /**
     * EasyExcel 批量入库
     */
    @PostMapping("/batch/upload/")
    @ResponseBody
    public ResponseModel upload(@RequestParam("file") MultipartFile files) throws IOException {
        InputStream inputStream = files.getInputStream();
        EasyExcel.read(inputStream, ArchivesBatchImport.class, new ArchivesBatchListener()).sheet().doRead();
        return ResponseModel.success("上传成功");
    }


    public static String getFileSize(MultipartFile file) {
        long fileSize = file.getSize();
        if (fileSize < 1024) {
            return fileSize + " bytes";
        } else if (fileSize < 1024 * 1024) {
            return fileSize / 1024 + " KB";
        } else {
            return fileSize / (1024 * 1024) + " MB";
        }
    }

    /**
     * 上传电子档案文件
     */
    @PostMapping("/upload/electron/file")
    @ResponseBody
    public Map<String, Object> uploadFile(@RequestPart("file") MultipartFile file,
                                          @RequestParam(value = "archivesId", required = false) String archivesId) {
        Map<String, Object> resMap = new HashMap<>();
        //获取文件名
        String fileName = file.getOriginalFilename();
        //获取文件后缀名。也可以在这里添加判断语句，规定特定格式的图片才能上传，否则拒绝保存。
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //为了避免发生图片替换，这里使用了文件名重新生成
        fileName = UUID.randomUUID() + suffixName;
        //拼接前缀路径
        LocalDateTime localDateTime = LocalDateTime.now();
        String middlePath = localDateTime.getYear() + File.separator + localDateTime.getMonthValue();
        SysParamset sysParamset = sysParamsetMapper.selectById(1);
        String basePathJoin = sysParamset.getParamValue() + File.separator + middlePath;
        if (!FileUtil.exist(basePathJoin)) {
            File file1 = FileUtil.mkdir(basePathJoin);
        }
        try {
            File savePath = new File(basePathJoin + File.separator + fileName);
            //将图片保存到文件夹里
            file.transferTo(savePath);
            //返回文件的路径
            String nginx = nginxPath + middlePath + File.separator + fileName;
            resMap.put("data", nginx);
            resMap.put("msgName", "图片保存成功");
            resMap.put("code", 0);
            ElectronArchives electronArchives = new ElectronArchives();
            if (StrUtil.isNotEmpty(archivesId)) {
                electronArchives.setArchivesId(Convert.toInt(archivesId));
            }
            electronArchives.setElectronFile(nginx);
//                electronArchives.setDocumentName(documentName.toString());
//                electronArchives.setDocumentPlacename(documentPlaceName.toString());
//                electronArchives.setDocumentNumber(documentNumber.toString());
//                electronArchives.setDocumentTime(documentTime.toString());
            electronArchives.setCreateTime(DateFormat.getTime());
            electronArchives.setUploadFileName(file.getOriginalFilename());
            electronArchives.setSavePath(savePath.getAbsolutePath());
            electronArchives.setUpdateTime(DateFormat.getTime());
            String fileSize = getFileSize(file);
            electronArchives.setFileSize(fileSize);
            electronArchivesMapper.insert(electronArchives);
            resMap.put("electronId", electronArchives.getId());
            resMap.put("fileName", file.getOriginalFilename());
            resMap.put("fileSize", fileSize);
            resMap.put("dateTime", DateFormat.getTime());
            return resMap;
        } catch (Exception e) {
            e.printStackTrace();
            resMap.put("code", 1);
            return resMap;
        }
    }

}
